# in module.py

# class User:
#     pass
#
# user = User()

# in test.py

# from module import user


class User:
    # def __new__(cls, *args, **kwargs):
    #     if not hasattr(cls, "sharedInstance"):
    #         s = super().__new__(cls, *args, **kwargs)
    #         setattr(cls, "sharedInstance", s)
    #
    #     s = getattr(cls, "sharedInstance")
    #     return s

    def __init__(self):
        self._age = 0
        self.name = None

    @property
    def age(self):
        # TODO: if self._age == 0 else query sql or cache
        return self._age

    @age.setter
    def age(self, value):
        if value > 30:
            raise ValueError
        self._age = value

    def __eq__(self, other):
        assert isinstance(other, User)
        return self.username == other.username

    def __add__(self, other):
        pass

    def __iadd__(self, other):
        self.username += other
        u = User()
        u.username = self.username + other
        return u

    # def __and__(self, other):
    #     pass
    #
    # def __or__(self, other):
    #     pass
    #
    # def __gt__(self, other):
    #     pass
    # def __ge__(self, other):
    #     pass
    #
    # def __lt__(self, other):
    #     pass
    #
    # def __le__(self, other):
    #     pass

    def __bytes__(self):
        return b'\x01\x02\x03\x04'

    def __len__(self):
        return len(self.username)


class UserManager:
    def __init__(self):
        self._user_dict = dict()

    def __setitem__(self, key, value):
        self._user_dict[key] = value

    def __getitem__(self, item):
        return self._user_dict[item]

    def __contains__(self, item):
        return item in self._user_dict.keys()

    def __iter__(self):
        return self

    def __next__(self):
        if not hasattr(self, "ptr"):
            setattr(self, "ptr", 0)

        if self.ptr >= len(self._user_dict.values()):
            self.ptr = 0
            raise StopIteration
            # return None

        obj = list(self._user_dict.values())[self.ptr]
        self.ptr += 1
        return obj

        # for u in self._user_dict.keys():
        #     yield u


manager = UserManager()
bob = User()
john = User()

bob.username = "bob"
john.username = "john"
manager[bob.username] = bob
manager[john.username] = john

for u in manager:
    print(u.username)

# while True:
#     user = next(manager)
#     if user is None:
#         break
#     print(user.username)
#
# while True:
#     user = next(manager)
#     if user is None:
#         break
#     print(user.username)

# manager[bob.username] = bob
# manager[john.username] = john

# for user in manager:
#     print(user.username)

print(manager.__next__(), "-------------")
print(manager.__next__(), "-------------")


# um = UserManager()
# u = User()
# u.username = "bob"
#
# um[u.username] = u
# # u = um['bob']
#
# if 'bob' in um:
#     u = um['bob']
#
# u2 = User()
# u2.username = "bob"
#
# if u == u2:
#     print("There are two users named bob")


# u2 += "_hello"
# print(u2.username)
# u2 = u2 + "_good"

# b = bytes(u2)
# print(len(u2))
# pass

# class FileManager:
#     class FileParser:
#         def __init__(self, fp):
#             self.fp = fp
#
#         def parse(self):
#             raise NotImplementedError
#
#     class JsonParser(FileParser):
#         def parse(self):
#             import json
#             return json.load(self.fp)
#
#     class XMLParser(FileParser):
#         def parse(self):
#             pass
#
#     def __init__(self, path):
#         self.file_path = path
#         self.fp = open(self.file_path)
#
#     def __enter__(self):
#         suffix = self.file_path.rsplit(".", 1)[-1]
#         if suffix == "json":
#             return FileManager.JsonParser(self.fp)
#         elif suffix == "xml":
#             return FileManager.XMLParser(self.fp)
#         raise Exception("Unsupported file format.")
#
#     def __exit__(self, exc_type, exc_val, exc_tb):
#         self.fp.close()


# fm = FileManager("./test.json")
# with fm as fp:
#     p = fp.parse()
#     print(p)
#
# # new lock for threading.
#
# import threading
#
# lock = threading.Lock()
#
# with lock:
#     # TODO
#     pass
#
# foo_list = []
#
#
# def test(foo):
#     foo_list.append(foo)
#
#     def warpper(*args, **kwargs):
#         return foo(*args, **kwargs)
#
#     return warpper
#
#
# @test
# def foo():
#     print(11)
#
#
# @test
# def foo1():
#     print(22)
#
#
# class Request:
#     def __init__(self):
#         self.method = None
#
#
# def allow_methods(methods):
#     print("func name: allow_methods")
#     def func(f):
#         print("func name: func")
#         def wrapper(request, *args, **kwargs):
#             print("func name: wrapper")
#             assert isinstance(request, Request)
#             if request.method not in methods:
#                 raise Exception("Unsupported methods")
#             return f(request, *args, **kwargs)
#
#         return wrapper
#
#     return func
#
#
# @allow_methods(["GET"])
# def get_user_view(request):
#     print("get_user_view is called.")
#
#
# # @allow_methods(["POST", "UPDATE"])
# # def get_html_view(reqeust):
# #     print("get_html_view is called")
#
# r = Request()
# r.method = "GET"
#
# get_user_view(r)
# # get_html_view(r)
#
#
# class A:
#     def dec(self, *args ,**kwargs):
#         pass
#
#
# a = A()
#
# @a.dec
# def func1():
#     pass
#
# def logger(text):
#     def outerwrapper(fun):
#         def wrapper(*args,**kwargs):
#             print('----------2---------','\n',text)
#             return fun(*args,**kwargs)
#         return wrapper
#     return outerwrapper
#
# class Ab:
#     @logger("---------3---------")
#     def dec(self):
#         print("--------1-------")
#
# if __name__ == '__main__':
#     ab=Ab()
#     ab.dec()

# http_regex = "((?P<schema>(http(s)?))://)?(?P<domain>[\\w\.-]+)(?P<path>([\/\\w\%\.]+))?(\?(?P<arguments>[^\\s]+))?"
# import re
#
# m = re.match(http_regex, "https://www.baidu.com/user/index.html?username=zhangshan&age=34")
# print(m.group("schema"))

def get_name():
    return "xyz"


class A:
    description = "This is description"

    def __init__(self):
        self.name = "zhangshan"
        self.__dict__["age"] = 34
        setattr(self, "addr", "chengdu")

    def __getattr__(self, item):
        pass

    def get_name(self):
        pass


tmp_list = []
# data_list = []


def C(p, a, n):
    if len(tmp_list) >= n:
        yield list(tmp_list)
        # data_list.append(list(tmp_list))
        return

    for i in range(p, len(a)):
        tmp_list.append(a[i])
        for d in C(i + 1, a, n):
            yield d
        tmp_list.pop()


a = (1,2,3,4,5,6,7,8,9)
# a = (1, 2, 3, 4)
# C(0, a, 3)

for d in C(0, a ,3):
    print(d)

# print(data_list)
# print(a.description)
# print(a.name, a.age, a.addr, a.description, a.__class__.description, a.__class__.__dict__["description"])
